package com.siwei.mes.sync.tc.service;

import cn.hutool.core.collection.CollectionUtil;
import com.siwei.mes.common.util.DateHelper;
import com.siwei.mes.common.util.JsonUtils;
import com.siwei.mes.entity.ShxhSynchronizedata;
import com.siwei.mes.entity.dto.SupplierCompanyMaterialsSelfSupplyDto;
import com.siwei.mes.entity.experiment.*;
import com.siwei.mes.entity.laboratory.ImportList;
import com.siwei.mes.entity.laboratory.WtSample;
import com.siwei.mes.entity.materials.Materials;
import com.siwei.mes.entity.sync.tc.SupplyTask;
import com.siwei.mes.entity.sync.tc.Waybill;
import com.siwei.mes.entity.system.Signature;
import com.siwei.mes.entity.system.SupplierCompany;
import com.siwei.mes.entity.system.TestProjectInfo;
import com.siwei.mes.enums.*;
import com.siwei.mes.mapper.ShxhSynchronizedataMapper;
import com.siwei.mes.mapper.experiment.*;
import com.siwei.mes.mapper.laboratory.ImportListMapper;
import com.siwei.mes.mapper.laboratory.WTSampleMapper;
import com.siwei.mes.mapper.materials.SupplierCompanyMapper;
import com.siwei.mes.mapper.materials.SupplierCompanyMaterialsMapper;
import com.siwei.mes.mapper.syncTc.WaybillMapper;
import com.siwei.mes.mapper.system.SignatureMapper;
import com.siwei.mes.mapper.system.TestProjectInfoMapper;
import com.siwei.mes.service.experiment.ExperimentDetailService;
import com.siwei.mes.service.experiment.ExperimentMessageService;
import com.siwei.mes.service.experiment.ExperimentService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * 生成原材料抽象
 *
 * @Description: 生成原材料抽象
 * @Version: 1.0
 * @author: mlchen
 * @date: 2025/3/8 01:01
 */
@Service
public class GenMaterialAbstractService {
    private static final Logger log = LoggerFactory.getLogger("tc");
    @Resource
    private ExperimentMapper experimentMapper;
    @Resource
    private ExperimentService experimentService;
    @Resource
    private SupplierCompanyMaterialsMapper supplierCompanyMaterialsMapper;
    @Resource
    private SupplierCompanyMapper supplierCompanyMapper;
    @Resource
    private TestProjectInfoMapper testProjectInfoMapper;
    @Resource
    private ExperimentDetailMapper experimentDetailMapper;
    @Resource
    private ExperimentSampleSmokeMapper experimentSampleSmokeMapper;
    @Resource
    private ExperimentMessageService experimentMessageService;
    @Resource
    private ExperimentWaybillMapper experimentWaybillMapper;
    @Resource
    private ExperimentSupplyTaskMapper experimentSupplyTaskMapper;
    @Resource
    private WaybillMapper waybillMapper;
    @Resource
    private ExperimentDetailService experimentDetailService;
    @Resource
    private ShxhSynchronizedataMapper shxhSynchronizedataMapper;
    @Resource
    private WTSampleMapper wtSampleMapper;
    @Resource
    private ImportListMapper importListMapper;
    @Resource
    private ExperimentSignatureMapper experimentSignatureMapper;
    @Resource
    private SignatureMapper signatureMapper;

    /**
     * 通过运单新增委托
     *
     * @param mesType             砼材类型
     * @param checkType           1-快检 2-批检
     * @param entity              运单信息
     * @param supplyTask          任务信息
     * @param materials           物料信息
     * @param behalfNumber        代表数量
     * @param entrustExperiment   委托类型
     * @param testProjectCodeList 试验项目集合
     */
    public Experiment createExperimentInfoByWaybillInfo(TcContrastExperimentTypeEnum mesType,
                                                        Integer checkType,
                                                        Waybill entity,
                                                        SupplyTask supplyTask,
                                                        Materials materials,
                                                        Double behalfNumber,
                                                        String entrustExperiment,
                                                        Set<String> testProjectCodeList) {
        log.info("开始执行通过新增【{}】试验委托，运单id:【{}】,任务单id:【{}】,检测类型:【{}】,代表数量：:【{}】", mesType.getName(), entity.getWaybillId(), supplyTask.getId(), checkType, behalfNumber);
        Experiment experiment = experimentService.getExperimentInfoByWaybillInfo(entity, checkType, entrustExperiment, mesType.getMesType(), testProjectCodeList);
        if (materials.getSpecId() != null) {
            if (StringUtils.isNotEmpty(materials.getMaterialAbbreviation())) {
                experiment.setSampleLevel(materials.getMaterialAbbreviation() + materials.getMaterialsConfigSpec());
                experiment.setMaterialAbbreviation(materials.getMaterialAbbreviation());
            } else {
                experiment.setSampleLevel(materials.getMaterialsConfigName() + materials.getMaterialsConfigSpec());
            }
            experiment.setSpecId(materials.getSpecId());
        } else {
            experiment.setSampleLevel(materials.getMaterialName() + materials.getMaterialSpecs());
        }

        /**因为这里是拆单的这里要赋值代表数量*/
        if (behalfNumber != null) {
            experiment.setBehalfNumber(behalfNumber);
        }

        experiment.setMatterName(materials.getMaterialName());
        experiment.setMatterSpecs(materials.getMaterialSpecs());
        experiment.setMaterialsName(materials.getMaterialsConfigName());
        experiment.setMaterialsSpecs(materials.getMaterialsConfigSpec());
        experiment.setMaterialsId(String.valueOf(materials.getId()));
        /**如果简称为空 赋值全称*/
        String abbreviation = materials.getMaterialAbbreviation();
        experiment.setMaterialAbbreviation(StringUtils.isBlank(abbreviation) ? experiment.getMaterialsName() : materials.getMaterialAbbreviation());
        experiment.setMatterAbbreviation(StringUtils.isBlank(abbreviation) ? experiment.getMaterialsName() : materials.getMaterialAbbreviation());
        experiment.setFactory(supplyTask.getFactory());
        experiment.setFactoryCalled(supplierCompanyMaterialsMapper.getFactoryCalledListByMaterialsType(mesType.getMesType(), supplyTask.getFactory()));

        experiment.setSupplyCompanyName(entity.getSupplyCompanyCompany());
        /**这里根据供应商名称去查询*/
        SupplierCompany supplierCompany = supplierCompanyMapper.selectBySupplierNameMaterials(entity.getSupplyCompanyCompany(), entity.getProjectName(), entity.getProjectSpecs(), entity.getProjectCategory());
        if (supplierCompany != null) {
            /**取erp的名称是最新的*/
            experiment.setSupplyCompanyName(supplierCompany.getErpCompanyName());
            experiment.setSupplyCompanyCalled(supplierCompany.getSupplierAbbreviation());
            experiment.setCertificateNo(supplierCompany.getCertificateNo());
        }
        /**给新加的是否甲供字段赋值*/
        SupplierCompanyMaterialsSelfSupplyDto supplierCompanyMaterialsSelfSupplyDto = new SupplierCompanyMaterialsSelfSupplyDto().setMaterialsId(Long.valueOf(experiment.getMaterialsId())).setSpecId(experiment.getSpecId())
                .setSupplierCompanyName(experiment.getSupplyCompanyName()).setManufacturers(experiment.getFactory()).setManufacturersCalled(experiment.getFactoryCalled());
        List<SupplierCompanyMaterialsSelfSupplyDto> selfSupplyList = supplierCompanyMaterialsMapper.getMaterialsSelfSupplyList(supplierCompanyMaterialsSelfSupplyDto);
        if(CollectionUtil.isNotEmpty(selfSupplyList)){
            experiment.setSelfSupply(SelfSupplyEnum.YES.getCode());
        }else{
            experiment.setSelfSupply(SelfSupplyEnum.NO.getCode());
        }
        experimentMapper.insertSelective(experiment);

        /**生成对应试验台账详情信息*/
        if (!testProjectCodeList.isEmpty()) {
            List<ExperimentDetail> detailList = new ArrayList<>();
            /**查询所有试验项目信息*/
            List<TestProjectInfo> testProjectInfoList = testProjectInfoMapper.selectByTestProjectCodeList(testProjectCodeList);
            for (TestProjectInfo testProjectInfo : testProjectInfoList) {
                ExperimentDetail detail = new ExperimentDetail();
                detail.setExperimentId(experiment.getId());
                detail.setCheckType(CheckEnum.BATCH.getCode());
                detail.tcInit(true);
                detail.setTestProjectCode(testProjectInfo.getTestCode());
                detail.setTestProjectName(testProjectInfo.getTestName());
                detail.setObjJson(testProjectInfo.getObjJson());
                /**如果是粗骨料筛分析，需要重新组装json*/
                if (testProjectInfo.getTestCode().equals(TestProjectEnum.COARSE_AGGREGATE_PARAM_CGL_SFX.getCode())) {
                    detail.setSfxJson(experiment, detail);
                }
                experimentDetailService.payloadOtherInfo(detail, testProjectInfo.getTestCode(), experiment.getExperimentType());
                detailList.add(detail);
            }
            if (!detailList.isEmpty()) {
                experimentDetailMapper.insertList(detailList);
            }

            /**新增对应快检的抽样信息 */
            for (TestProjectInfo testProjectInfo : testProjectInfoList) {
                ExperimentSampleSmoke sampleSmoke = new ExperimentSampleSmoke();
                sampleSmoke.setId(null);
                sampleSmoke.tcInit(true);
                sampleSmoke.setExperimentId(experiment.getId());
                sampleSmoke.setSampleTime(new Date());
                sampleSmoke.setIsTestBlock(0);// 是否是试块 1-是 0-不是
                sampleSmoke.setSamplePersonName(experiment.getEntrustPersonName());
                sampleSmoke.setDisposerPersonName(experiment.getEntrustPersonName());
                sampleSmoke.setTestProjectCode(testProjectInfo.getTestCode());
                sampleSmoke.setTestProjectName(testProjectInfo.getTestName());
                sampleSmoke.setSampleUse(testProjectInfo.getTestName());
                if (-1 != testProjectInfo.getSampleQuantity()) {
                    sampleSmoke.setSampleQuantity(testProjectInfo.getSampleQuantity());
                }
                experimentSampleSmokeMapper.insertSelective(sampleSmoke);
            }
        }
        /**新增试验台账消息通知记录*/
        experimentMessageService.saveExperimentMessage(experiment);

        /**新增试验台账与电子签名关系记录*/
        ExperimentSignature experimentSignature = new ExperimentSignature();
        experimentSignature.setExperimentId(experiment.getId());
        Signature signature =signatureMapper.loadById(1L);
        if(signature != null){
            experimentSignature.setSignatureJson(JsonUtils.beanToObject(signatureMapper.loadById(1L)));
        }
        experimentSignatureMapper.insert(experimentSignature);

        return experiment;
    }

    /**
     * 试验委托和运单关系、试验委托和供货任务关系、修改运单状态
     *
     * @param experimentId 试验委托id
     * @param waybillId    运单id
     * @param supplyTaskId 供货任务id
     * @param behalfNumber 代表数量
     * @param isQuick      是否快检
     */
    public void handleExperimentRelations(Long experimentId, Long waybillId, Long supplyTaskId, double behalfNumber, boolean isQuick) {
        if (experimentId == null || waybillId == null || supplyTaskId == null) {
            log.warn("实验ID、运单ID或供货任务ID为空，无法创建关系");
            return;
        }
        log.info("开始操作试验委托和运单关系、试验委托和供货任务关系、修改运单状态。experimentId:【{}】,waybillId:【{}】,supplyTaskId:【{}】,behalfNumber:【{}】,isQuick：【{}】", experimentId, waybillId, supplyTaskId, behalfNumber, isQuick);

        /**新增试验台账与电子签名关系记录*/
        ExperimentSignature experimentSignature = new ExperimentSignature();
        experimentSignature.setExperimentId(experimentId);
        Signature signature = signatureMapper.loadById(1L);
        if(signature != null){
            experimentSignature.setSignatureJson(JsonUtils.beanToObject(signatureMapper.loadById(1L)));
        }
        experimentSignatureMapper.insert(experimentSignature);

        /**快检/批检与试验台账和运单的关系*/
        ExperimentWaybill experimentWaybill = new ExperimentWaybill()
                .setExperimentId(experimentId)
                .setWaybillId(waybillId)
                .setBehalfNumber(behalfNumber);
        experimentWaybillMapper.insertSelective(experimentWaybill);

        /**快检/批检与试验台账和供货任务的关系*/
        ExperimentSupplyTask experimentSupplyTask = new ExperimentSupplyTask()
                .setExperimentId(experimentId)
                .setSupplyTaskId(supplyTaskId);
        if (experimentSupplyTaskMapper.selectOne(experimentSupplyTask) == null) {
            experimentSupplyTask.setCreateTime(new Date());
            experimentSupplyTask.setReadTime(null);
            experimentSupplyTaskMapper.insertSelective(experimentSupplyTask);

            /**这里新增任务单的关联关系 给对应试验委托的isNewTask改为1*/
            log.info(this.getClass().getName() + "新增任务单给对应isNewTask修改为1");
            experimentMapper.updateIsNewTask(experimentId, 1);
        }

        Waybill waybill = new Waybill().setId(waybillId);
        if (isQuick) {
            waybill.setIsQuick(1);
            /**已生成委托数量*/
            log.info("对应运单id：【{}】，已生成批检委托数量添加：【{}】", waybillId, behalfNumber);
            waybillMapper.updateGenQuickQuantity(waybillId, behalfNumber);
        } else {
            waybill.setIsBatch(1);
            /**已生成委托数量*/
            log.info("对应运单id：【{}】，已生成批检委托数量添加：【{}】", waybillId, behalfNumber);
            waybillMapper.updateGenBatchQuantity(waybillId, behalfNumber);
        }
        // 更新运单状态
        waybillMapper.updateByPrimaryKeySelective(waybill);

        /**修改这个试验台账的代表数量 == 所有跟这个试验台账相关的运单签收数量之和*/
        List<Waybill> waybillList = experimentWaybillMapper.selectByExperimentId(experimentId);
        Double behalfNumberSum = null;
        if (!waybillList.isEmpty()) {
            behalfNumberSum = waybillList.stream().map(Waybill::getBehalfNumber).reduce((double) 0, Double::sum);
            Experiment experiment = new Experiment();
            experiment.setId(experimentId);
            experiment.setBehalfNumber(behalfNumberSum);
            experiment.tcInit(false);
            experimentMapper.updateByPrimaryKeySelective(experiment);
        }

        //更新协会的代表数量
        List<ShxhSynchronizedata> list = shxhSynchronizedataMapper.getList(new ShxhSynchronizedata().setExperimentId(experimentId));
        if (list == null || list.isEmpty()) {
            log.info("未查询到对应的协会关联信息，暂不更新代表数量！品控台账id:" + experimentId);
            return;
        }
        Experiment experiment = experimentMapper.loadById(experimentId);
        if (experiment == null) {
            log.info("未查询到对应的试验台账信息，暂不更新代表数量！");
            return;
        }
        if (!ExperimentStatusEnum.IN_TEST.getCode().equals(experiment.getExperimentStatus())) {
            log.info("只更新品控试验状态为实验中的委托，暂不更新代表数量！品控台账id:" + experimentId);
            return;
        }
        ShxhSynchronizedata synchronizedata = list.get(0);

        if (StringUtils.isNotBlank(synchronizedata.getSampleNo())) {
            WtSample wS = new WtSample();
            wS.setDelegateQuan(behalfNumberSum == null ? "0" : String.valueOf(behalfNumberSum));
            wS.setSampleNo(synchronizedata.getSampleNo());

            //修改WtSample 代表数量信息
            wtSampleMapper.updateWtSampleDelegateQuan(wS);
        }

        if (StringUtils.isNotBlank(synchronizedata.getImportId())) {
            ImportList importList = new ImportList().setImportId(synchronizedata.getImportId());
            importList.setProdinQuan(behalfNumberSum == null ? "0" : String.valueOf(behalfNumberSum));

            //修改原材料进料 代表数量信息
            importListMapper.updateImportListProdinQuan(importList);
        }
    }

    /**
     * @param checkType       检测类型
     * @param testProjectCode 试验项目code
     * @param materials       物料信息
     */
    public boolean isAddExperimentByCheckType(int checkType, String testProjectCode, Materials materials) {
        CheckTypeEnum checkTypeEnum = CheckTypeEnum.selectByCode(checkType);
        if (checkTypeEnum == null) {
            return false;
        }
        Date endDate = new Date();
        Date startDate = DateHelper.getDateByCheckType(checkType);
        Experiment experiment = new Experiment();
        experiment.setStartTime(DateHelper.formatDateTimeDefaultFormat(startDate));
        experiment.setEndTime(DateHelper.formatDateTimeDefaultFormat(endDate));
        experiment.setMaterialsName(materials.getMaterialsConfigName());
        experiment.setMaterialsSpecs(materials.getMaterialsConfigSpec());
        experiment.setTestProjectCode(testProjectCode);
        log.info("查询对应原材料是否存在对应检测类型【{}】，试验项目code【{}】，物料名称【{}】，物料规格【{}】的试验台账信息",
                checkTypeEnum.getName(), testProjectCode, materials.getMaterialsConfigName(), materials.getMaterialsConfigSpec());
        return experimentMapper.countExperiment(experiment) > 0;
    }

    /**
     * 获取double值
     *
     * @param bigDecimal
     * @return
     */
    public double getDoubleValue(BigDecimal bigDecimal) {
        double doubleValue = 0;
        if (bigDecimal != null) {
            doubleValue = bigDecimal.doubleValue();
        }
        if (doubleValue < 0) {
            doubleValue = 0;
        }
        return doubleValue;
    }
}
